package controller.billing;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;
import java.util.Vector;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;

import controller.GUIAbstractController;
import controller.billing.document.BillDocumentCreator;

import model.Belegung;
import model.Kunde;
import model.Rechnung;
import model.Reservierung;

import view.billing.CreateBillView;

public class GuiCreateBillViewController extends GUIAbstractController implements ActionListener, DocumentListener, ItemListener, ListSelectionListener {

	private CreateBillView billView;
	private BillDocumentCreator billDocumentCreator = new BillDocumentCreator();
	
	public GuiCreateBillViewController() {
		super();
		this.billView = new CreateBillView();
		this.billView.addEventListeners(this);
	
		ReservationTableModel tableModel = new ReservationTableModel();
		billView.getTableReservations().setModel(tableModel);
		
		reloadData();
	}

	private void reloadData() {
		
		Date von = getDateOfTextFieldValue(billView.getTxtArrival());
		Date bis = getDateOfTextFieldValue(billView.getTxtDeparture());
		String nachname = getTextFieldValue(billView.getTxtCustomer());
		String zimmername = getTextFieldValue(billView.getTxtRoom());
		boolean onlyUnpayed = billView.getCheckShowUnpayedOnly().isSelected();
		List<Reservierung> reservations = super.dbController.filter(von, bis, nachname, zimmername, onlyUnpayed);
	    
		// addDummyData(reservations);
			
	    ReservationTableModel model= new ReservationTableModel(); 
	    model.setReservations(reservations);
	    billView.getTableReservations().setModel(model);
	}

	
	public CreateBillView getView() {
		return billView;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == billView.getBtnClearArrival()){
			billView.getTxtArrival().setText("");
			reloadData();
		}else if(e.getSource() == billView.getBtnClearCustomer()){
			billView.getTxtCustomer().setText("");
			reloadData();
		}else if(e.getSource() == billView.getBtnClearDeparture()){
			billView.getTxtDeparture().setText("");
			reloadData();
		}else if(e.getSource() == billView.getBtnCreateBill()){
			createBillForSelectedCustomer();
		}else if(e.getSource()==billView.getBtnDeleteReservation()){
			deleteSelectedReservation();
		}
	}

	private static String getTextFieldValue(JTextField textField){
		return textField.getText().length() > 0 ? textField.getText() : null;
	}
	
	private static Date getDateOfTextFieldValue(JTextField textField){
		String text = getTextFieldValue(textField);
		try{
			return new Date(Date.parse(text));
		}catch (Exception e) {
			return null;
		}
	}

	@Override
	public void insertUpdate(DocumentEvent e) {
		reloadData();
	}

	@Override
	public void removeUpdate(DocumentEvent e) {
		reloadData();
	}

	@Override
	public void changedUpdate(DocumentEvent e) {
		reloadData();
	}

	
	@Override
	public void itemStateChanged(ItemEvent e) {
		reloadData();
	}

	@Override
	public void valueChanged(ListSelectionEvent e) {
		int index= billView.getTableReservations().getSelectedRow();
		Vector<Kunde> kunden = new Vector<Kunde>();
		
		if(index > -1){
			ReservationTableModel model = (ReservationTableModel) billView.getTableReservations().getModel();
			Reservierung selectedRes = model.getReservations().get(index);
			
			List<Belegung> belegungen = selectedRes.getBelegungen();
			
			// Add kunden to combobox model
			for(Belegung b : belegungen){
				kunden.addAll(b.getKunden());
			}
		}
		
		billView.getCbxCustomer().setModel(new DefaultComboBoxModel(kunden));
	}
	
	private Rechnung createBillForSelectedCustomer(){
		
		// obtain selected reservation
		int index = billView.getTableReservations().getSelectedRow();
		if(index > -1){
			ReservationTableModel model = (ReservationTableModel) billView.getTableReservations().getModel();
			Reservierung reservation =  model.getReservations().get(index);
			
			//obtain paying customer from combo box
			Kunde kunde = (Kunde) billView.getCbxCustomer().getSelectedItem();
			
			//obtain date for payment from txtfield
			Date paymentDate = billView.getDateOfDepartureForBill();
			
			Rechnung b = new Rechnung(reservation);
			b.setDatum(paymentDate);
			b.setPayingCustomer(kunde);
			b.calculatePreis();
			
			reservation.setRechnung(b);
			super.dbController.saveEntity(b);
			super.dbController.saveEntity(reservation);
			
			try {
				billDocumentCreator.createBillDocument(b);
			} catch (IOException e) {
				e.printStackTrace();
			}
			reloadData();
			return b;
		}
		else{
			throw new RuntimeException("No Reservation selected for bill creation!");
		}
	}
	public void deleteSelectedReservation(){
		int index = billView.getTableReservations().getSelectedRow();
		if(index > -1){
			ReservationTableModel model = (ReservationTableModel) billView.getTableReservations().getModel();
			Reservierung reservation =  model.getReservations().get(index);
			
			//obtain paying customer from combo box
			Kunde kunde = (Kunde) billView.getCbxCustomer().getSelectedItem();
			
			//storno date is always arrival date
			Date paymentDate = reservation.getVon();
			
			Rechnung b = new Rechnung(reservation);
			b.setDatum(paymentDate);
			b.setPayingCustomer(kunde);
			b.calculatePreis();

			try {
				billDocumentCreator.createBillDocument(b);
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			reservation.clearRechnung();
			super.dbController.deleteEntity(reservation);
			reloadData();
		}
		else{
			throw new RuntimeException("No Reservation can be deleted!");
		}
	}

}
